#ifndef MRF_H
#define MRF_H

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <vector>
#include "systeminclude.h"
using namespace std;

//How many classes
#ifndef NUM_CLUSTERS
#define NUM_CLUSTERS 4
#endif
//#define CLASS_NUMBER 4

// How many times repeat relabeling
#define ITERATION_NUMBER 2

// Beta value for MRF energy count
#define MRF_BETA 5.008

// What's the color channel number
#define COLOR_CHANNEL_NUMBER 3

class MRF
{
public:
	MRF(void);
	~MRF(void);
	void initLearningMRF(IplImage *img);
	void initFastMRF(IplImage *img, IplImage *labelimg);
	IplImage* getLabelledImage();
	void ouputLabelledImage();
	void setMeansAndVariances(const CvMat *means, const CvMat **variances);

protected:
	
	vector< float > means;
	vector< float > variances;
	IplImage *img;

	// Label info
	IplImage* labelImage;
	uchar* labelData;
	CvMat* labelMatrix;
	int labelStep;

	// Img info
	int width, height, step, channels;
	uchar* data;

private:
	void countMeansAndVariances();
	void defaultLabel();
	void calculateMRFWithLearning();
	void calculateMRF();
	
	float calculateEnergy(int energyClass, int i, int j);
	float calculateGibbsEnergy(int energyClass, int i, int j);
	void imageLabelFromEM(IplImage *img);
	vector<int> getColorSpace(vector<int> I);
	float getColorSpaceAvg(int R, int G, int B);

};

#endif